/* -*-c++-*- 
 * This source code is proprietary of ADIT
 * Copyright (C) 2013 Advanced Driver Information Technology Joint Venture GmbH
 * All rights reserved
 *
 * Author: Guruprasad Patkar <Guruprasad.SureshPatkar@in.bosch.com>
 * Author: Rudolf Dederer <rudolf.dederer@de.bosch.com>
*/

#ifndef OSGBATCHEDTEXT_VEC_ARRAY
#define OSGBATCHEDTEXT_VEC_ARRAY 1

#include <vector>
#include <osg/Referenced>
#include <osg/Vec2h>
#include <osg/Vec3h>
#include <osg/Vec4h>
#include <osg/Vec2f>
#include <osg/Vec3f>
#include <osg/Vec4f>
#include <osgBatchedText/Export>

namespace osgBatchedText {

class OSGBATCHEDTEXT_EXPORT ArrayBase : public osg::Referenced
{
public:

   ArrayBase() {}
   ~ArrayBase() {}

   virtual bool empty() const = 0;
   virtual void clear() = 0;
   virtual unsigned int size() const = 0;
   virtual unsigned int capacity() const = 0;
   virtual void reserve(const unsigned int& num) = 0;
   virtual void resize(const unsigned int& num) = 0;
   virtual unsigned int getDataTypeSize() const = 0;
};

template <typename T>
class OSGBATCHEDTEXT_EXPORT VecArray : public ArrayBase
{
public:

   VecArray() {}
   ~VecArray() {}

   virtual bool empty() const { return _vector.empty(); }
   virtual void clear() { _vector.clear(); }
   virtual unsigned int size() const { return _vector.size(); }
   virtual unsigned int capacity() const { return _vector.capacity(); }
   virtual void reserve(const unsigned int& num) { _vector.reserve(num); }
   virtual void resize(const unsigned int& num) { _vector.resize(num); }
   virtual unsigned int getDataTypeSize() const { return sizeof(T); }

   std::vector<T>& asVector() { return _vector; }
   const std::vector<T>& asVector() const { return _vector; }

private:
   std::vector<T> _vector;
};

OSGBATCHEDTEXT_EXPORT void convertToHalfFloatVector(const std::vector<float>& src, std::vector<half_float::half>& dst);
OSGBATCHEDTEXT_EXPORT void convertToHalfFloatVector(const std::vector<osg::Vec2f>& src, std::vector<osg::Vec2h>& dst);
OSGBATCHEDTEXT_EXPORT void convertToHalfFloatVector(const std::vector<osg::Vec2f>& src, std::vector<osg::Vec3h>& dst);
OSGBATCHEDTEXT_EXPORT void convertToHalfFloatVector(const std::vector<osg::Vec3f>& src, std::vector<osg::Vec3h>& dst);
OSGBATCHEDTEXT_EXPORT void convertToHalfFloatVector(const std::vector<osg::Vec4f>& src, std::vector<osg::Vec4h>& dst);

OSGBATCHEDTEXT_EXPORT float convertToScaledHalfFloatVector(const std::vector<float>& src, std::vector<half_float::half>& dst);
OSGBATCHEDTEXT_EXPORT float convertToScaledHalfFloatVector(const std::vector<osg::Vec2f>& src, std::vector<osg::Vec2h>& dst);
OSGBATCHEDTEXT_EXPORT float convertToScaledHalfFloatVector(const std::vector<osg::Vec3f>& src, std::vector<osg::Vec3h>& dst);
OSGBATCHEDTEXT_EXPORT float convertToScaledHalfFloatVector(const std::vector<osg::Vec4f>& src, std::vector<osg::Vec4h>& dst);

class OSGBATCHEDTEXT_EXPORT FloatAndHalfFloat
{
public:
   FloatAndHalfFloat(float val) : _fl(val), _hf(val) {}
   FloatAndHalfFloat(half_float::half val) : _fl(val), _hf(val) {}
   float _fl;
   half_float::half _hf;
};

}

#endif // OSGBATCHEDTEXT_VEC_ARRAY
